﻿#include "SpriteStandObj.h"


Sprite::Box::Box():m_NumVertices(0),m_NumFaces(0),m_VB(0),m_IB(0),m_pCEffect(0),m_WVP(0),m_VertexLayout(0)
{
	D3DXMatrixIdentity(&m_Worldmat);
	m_pCD3d = Sprite::g_pCD3d;
}

Sprite::Box::~Box()
{
	ReleaseCOM(m_VB);
	ReleaseCOM(m_IB);
}

void Sprite::Box::init( float fScale )
{

	m_NumVertices = 8;
	m_NumFaces    = 12; // 2 per quad

	// Create vertex buffer
	SpriteVertex vertices[] =
	{
		{D3DXVECTOR3(-1.0f, -1.0f, -1.0f), WHITE},
		{D3DXVECTOR3(-1.0f, +1.0f, -1.0f), BLACK},
		{D3DXVECTOR3(+1.0f, +1.0f, -1.0f), RED},
		{D3DXVECTOR3(+1.0f, -1.0f, -1.0f), GREEN},
		{D3DXVECTOR3(-1.0f, -1.0f, +1.0f), BLUE},
		{D3DXVECTOR3(-1.0f, +1.0f, +1.0f), YELLOW},
		{D3DXVECTOR3(+1.0f, +1.0f, +1.0f), CYAN},
		{D3DXVECTOR3(+1.0f, -1.0f, +1.0f), MAGENTA},
	};

	// Scale the box.
	for(DWORD i = 0; i < m_NumVertices; ++i)
		vertices[i].m_Pos *= fScale;


	D3D10_BUFFER_DESC vbd;
	vbd.Usage = D3D10_USAGE_IMMUTABLE;
	vbd.ByteWidth = sizeof(SpriteVertex) * m_NumVertices;
	vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
	vbd.CPUAccessFlags = 0;
	vbd.MiscFlags = 0;
	D3D10_SUBRESOURCE_DATA vinitData;
	vinitData.pSysMem = vertices;
	HR(m_pCD3d->getDevice10()->CreateBuffer(&vbd, &vinitData, &m_VB));


	// Create the index buffer

	DWORD indices[] = {
		// front face
		0, 1, 2,
		0, 2, 3,

		// back face
		4, 6, 5,
		4, 7, 6,

		// left face
		4, 5, 1,
		4, 1, 0,

		// right face
		3, 2, 6,
		3, 6, 7,

		// top face
		1, 5, 6,
		1, 6, 2,

		// bottom face
		4, 0, 3, 
		4, 3, 7
	};

	D3D10_BUFFER_DESC ibd;
	ibd.Usage = D3D10_USAGE_IMMUTABLE;
	ibd.ByteWidth = sizeof(DWORD) * m_NumFaces*3;
	ibd.BindFlags = D3D10_BIND_INDEX_BUFFER;
	ibd.CPUAccessFlags = 0;
	ibd.MiscFlags = 0;
	D3D10_SUBRESOURCE_DATA iinitData;
	iinitData.pSysMem = indices;
	HR(m_pCD3d->getDevice10()->CreateBuffer(&ibd, &iinitData, &m_IB));
}

void Sprite::Box::draw()
{
	D3D10_TECHNIQUE_DESC techDesc;
	m_pCEffect->getTech()->GetDesc( &techDesc );
	for(UINT p = 0; p < techDesc.Passes; ++p)
	{
		m_pCEffect->getTech()->GetPassByIndex( p )->Apply(0);
		UINT stride = sizeof(SpriteVertex);
		UINT offset = 0;
		g_pCD3d->getDevice10()->IASetVertexBuffers(0, 1, &m_VB, &stride, &offset);
		g_pCD3d->getDevice10()->IASetIndexBuffer(m_IB, DXGI_FORMAT_R32_UINT, 0);
		g_pCD3d->getDevice10()->DrawIndexed(m_NumFaces*3, 0, 0);		
	}
	
}

void Sprite::Box::BuildEffect( std::wstring effectname )
{
	if (m_pCEffect)
	{
		Delete(m_pCEffect);
		
	}
	m_pCEffect = new SpriteEffect();
	m_pCEffect->initEffect(effectname);
	m_WVP = m_pCEffect->getFX()->GetVariableByName("gWVP")->AsMatrix();
}

void Sprite::Box::BuildVertexLayouts( void )
{

	// Create the vertex input layout.
	D3D10_INPUT_ELEMENT_DESC vertexDesc[] =
	{
		{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
		{"COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0}
	};

	// Create the input layout
	D3D10_PASS_DESC PassDesc;
	m_pCEffect->getTech()->GetPassByIndex(0)->GetDesc(&PassDesc);
	HR(m_pCD3d->getDevice10()->CreateInputLayout(vertexDesc, 2, PassDesc.pIAInputSignature,
		PassDesc.IAInputSignatureSize, &m_VertexLayout));
}

void Sprite::Box::setLayout(void)
{
	m_pCD3d->getDevice10()->OMSetDepthStencilState(0, 0);
	float blendFactors[] = {0.0f, 0.0f, 0.0f, 0.0f};
	m_pCD3d->getDevice10()->OMSetBlendState(0, blendFactors, 0xffffffff);
	m_pCD3d->getDevice10()->IASetInputLayout(m_VertexLayout);
	m_pCD3d->getDevice10()->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
};